package com.leyou.user.service.impl;

import com.leyou.user.mapper.UserMapper;
import com.leyou.user.pojo.User;
import com.leyou.user.service.UserService;
import com.leyou.common.utils.CodecUtils;
import com.leyou.common.utils.NumberUtils;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.amqp.core.AmqpTemplate;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.redis.core.StringRedisTemplate;
import org.springframework.stereotype.Service;

import java.util.Date;
import java.util.HashMap;
import java.util.Map;
import java.util.concurrent.TimeUnit;

@Service
public class UserServiceImpl implements UserService {
    @Autowired
    private UserMapper userMapper;
    @Autowired
    private AmqpTemplate amqpTemplate;
    @Autowired
    private StringRedisTemplate redisTemplate;
    @Autowired

    private static final String KEY_PREFIX = "user:code:phone:";
    private static final String KEY_PREFIX2 = "leyou:user:info";

    static final Logger logger = LoggerFactory.getLogger(UserService.class);

    //校验用户名和手机号是否可用
    @Override
    public Boolean checkData(String data, Integer type) {
        User record = new User();
        switch (type) {
            case 1:
                record.setUsername(data);
                break;
            case 2:
                record.setPhone(data);
                break;
            default:
                return null;
        }
        return userMapper.selectCount(record) == 0;
    }

    //发送手机验证码
    @Override
    public Boolean sendVerifyCode(String phone) {
        String code = NumberUtils.generateCode(6);
        try {
            //发送短信
            Map<String, String> msg = new HashMap<>();
            msg.put("phone", phone);
            msg.put("code", code);

            amqpTemplate.convertAndSend("leyou.sms.exchange", "sms.verify.code", msg);
            //将code存入redis
            redisTemplate.opsForValue().set(KEY_PREFIX + phone, code, 5, TimeUnit.MINUTES);
            return true;
        } catch (Exception e) {
            logger.error("发送短信失败。phone:{},code:{}", phone, code);
            return false;
        }
    }

    //用户注册
    @Override
    public Boolean register(User user, String code) {
        String key = KEY_PREFIX + user.getPhone();
        //1.从redis取出验证码
        String codeCache = redisTemplate.opsForValue().get(key);
        //2.校验短信验证码
        if (code == null && codeCache == null && !codeCache.equals(code)) {
            //不正确返回
            return false;
        }

        user.setId(null);
        user.setCreated(new Date());
        //3.密码加密
        String encodePassword = CodecUtils.passwordBcryptEncode(user.getUsername().trim(), user.getPassword().trim());
        user.setPassword(encodePassword);
        //4.写入数据库
        boolean result = userMapper.insertSelective(user) == 1;
        //5.如果注册成功，则删掉redis中的code
        if (result) {
            try {
                redisTemplate.delete(KEY_PREFIX + user.getPhone());
            } catch (Exception e) {
                logger.error("删除缓存验证码失败，code:{}", code, e);
            }
        }
        return result;
    }

    //用户验证
    @Override
    public User queryUser(String username, String password) {
        /**
         * 逻辑改变，先去缓存中查询用户数据，查到的话直接返回，查不到再去数据库中查询，然后放入到缓存当中
         */
        //1.查询
        User record = new User();
        record.setUsername(username);
        User user = this.userMapper.selectOne(record);

        //2.校验用户名
        if (user == null) {
            return null;
        }
        //3. 校验密码
        boolean result = CodecUtils.passwordConfirm(username + password, user.getPassword());
        if (!result) {
            return null;
        }

        //4.用户名密码都正确
        return user;
    }
}
